"""命令处理模块"""

import re
from datetime import datetime
from typing import List, Optional, Tuple
from nonebot import on_command, logger
from nonebot.adapters.onebot.v11 import Bot, GroupMessageEvent, Message, MessageSegment
from nonebot.params import CommandArg, ArgPlainText
from nonebot.permission import SUPERUSER
from sqlalchemy import and_, func, desc
from sqlalchemy.orm import Session
from .database import get_db_session, MessageRecord, init_db
from .config import config
from .utils import format_ranking_text, parse_at_message
from .generate_ranking_image import RankingImageGenerator
from .fix_avatar_helper import get_avatar_base64_from_url_async
import base64


# 查询命令
query_cmd = on_command("查询", aliases={"查看", "统计"}, priority=10, block=True)


@query_cmd.handle()
async def handle_query(bot: Bot, event: GroupMessageEvent, args: Message = CommandArg()):
    """处理查询命令"""
    try:
        init_db()
        
        group_id = str(event.group_id)
        user_id = str(event.user_id)
        target_user_id = user_id
        
        # 解析参数
        arg_text = args.extract_plain_text().strip()
        if arg_text:
            # 检查是否@了某人
            at_user_id = parse_at_message(str(args))
            if at_user_id:
                target_user_id = at_user_id
        
        # 查询数据库
        with get_db_session() as session:
            # 获取目标用户记录
            target_record = session.query(MessageRecord).filter(
                and_(
                    MessageRecord.group_id == group_id,
                    MessageRecord.user_id == target_user_id
                )
            ).first()
            
            if not target_record:
                await query_cmd.send("该用户暂无发言记录")
                return
            
            # 获取群内所有用户记录用于排名计算
            all_records = session.query(MessageRecord).filter(
                MessageRecord.group_id == group_id
            ).all()
            
            # 计算排名
            rankings = calculate_rankings(all_records, target_user_id)
            
            # 格式化输出
            result = format_user_stats(target_record, rankings)
            await query_cmd.send(result)
            
    except Exception as e:
        logger.error(f"查询命令处理失败: {e}")
        await query_cmd.send("查询失败，请稍后重试")


# 排行榜命令
ranking_cmd = on_command("发言榜", aliases={"昨日发言榜", "今日发言榜", "本周发言榜", "本月发言榜", "今年发言榜", "总发言榜"}, priority=10, block=True)


@ranking_cmd.handle()
async def handle_ranking(bot: Bot, event: GroupMessageEvent, args: Message = CommandArg()):
    """处理排行榜命令"""
    init_db()
    
    group_id = str(event.group_id)
    
    # 获取触发的命令
    raw_command = str(event.get_message()).strip()
    command_text = raw_command.split()[0] if raw_command else ""
    
    # 解析参数
    arg_text = args.extract_plain_text().strip()
    limit = config.message_counter_default_limit
    period = "today"  # 默认今日排行榜
    
    # 根据命令别名确定时间段
    if command_text == "昨日发言榜" or "昨日" in arg_text or "yesterday" in arg_text:
        period = "yesterday"
    elif command_text == "今日发言榜" or command_text == "发言榜":
        period = "today"
    elif command_text == "本周发言榜" or "本周" in arg_text or "week" in arg_text:
        period = "week"
    elif command_text == "本月发言榜" or "本月" in arg_text or "month" in arg_text:
        period = "month"
    elif command_text == "今年发言榜" or "今年" in arg_text or "year" in arg_text:
        period = "year"
    elif command_text == "总发言榜" or "总" in arg_text or "total" in arg_text:
        period = "total"
    
    # 解析数量参数
    if arg_text.isdigit():
        limit = min(int(arg_text), 50)  # 最多显示50个
    
    # 查询数据库
    with get_db_session() as session:
        # 根据时间段选择排序字段
        order_field = {
            "today": MessageRecord.today_count,
            "yesterday": MessageRecord.yesterday_count,
            "week": MessageRecord.week_count,
            "month": MessageRecord.month_count,
            "year": MessageRecord.year_count,
            "total": MessageRecord.total_count
        }[period]
        
        # 查询排行榜数据
        records = session.query(MessageRecord).filter(
            and_(
                MessageRecord.group_id == group_id,
                order_field > 0
            )
        ).order_by(desc(order_field)).limit(limit).all()
        
        if not records:
            await ranking_cmd.send(f"暂无{get_period_name(period)}发言记录")
            return
        
        # 格式化排行榜
        if config.message_counter_enable_image and len(records) > 0:
            # 生成图片
            image_data = await generate_ranking_image(records, period, group_id)
            if image_data:
                await ranking_cmd.send(MessageSegment.image(image_data))
                return
        
        # 如果图片生成失败或未启用，发送文本
        result = format_ranking_list(records, period, group_id)
        await ranking_cmd.send(result)





# 群排行榜命令
group_ranking_cmd = on_command("群发言榜", aliases={"群今日发言榜", "群昨日发言榜", "群本周发言榜", "群本月发言榜", "群今年发言榜", "群总发言榜"}, priority=10, block=True)


@group_ranking_cmd.handle()
async def handle_group_ranking(bot: Bot, event: GroupMessageEvent, args: Message = CommandArg()):
    """处理群排行榜命令"""
    init_db()
    
    # 获取触发的命令
    raw_command = str(event.get_message()).strip()
    command_text = raw_command.split()[0] if raw_command else ""
    
    # 解析参数
    arg_text = args.extract_plain_text().strip()
    limit = config.message_counter_default_limit
    period = "today"
    
    # 根据命令别名确定时间段
    if command_text == "群昨日发言榜" or "昨日" in arg_text:
        period = "yesterday"
    elif command_text == "群今日发言榜" or command_text == "群发言榜":
        period = "today"
    elif command_text == "群本周发言榜" or "本周" in arg_text:
        period = "week"
    elif command_text == "群本月发言榜" or "本月" in arg_text:
        period = "month"
    elif command_text == "群今年发言榜" or "今年" in arg_text:
        period = "year"
    elif command_text == "群总发言榜" or "总" in arg_text:
        period = "total"
    
    # 解析数量参数
    if arg_text.isdigit():
        limit = min(int(arg_text), 50)
    
    # 查询数据库
    with get_db_session() as session:
        # 根据时间段选择聚合字段
        count_field = {
            "today": MessageRecord.today_count,
            "yesterday": MessageRecord.yesterday_count,
            "week": MessageRecord.week_count,
            "month": MessageRecord.month_count,
            "year": MessageRecord.year_count,
            "total": MessageRecord.total_count
        }[period]
        
        # 按群组聚合数据
        group_stats = session.query(
            MessageRecord.group_id,
            MessageRecord.group_name,
            func.sum(count_field).label('total_count')
        ).filter(
            count_field > 0
        ).group_by(
            MessageRecord.group_id,
            MessageRecord.group_name
        ).order_by(
            desc('total_count')
        ).limit(limit).all()
        
        if not group_stats:
            await group_ranking_cmd.send(f"暂无{get_period_name(period)}群聊发言记录")
            return
        
        # 格式化群排行榜
        result = format_group_ranking_list(group_stats, period)
        await group_ranking_cmd.send(result)


# 初始化命令（仅超级用户）
init_cmd = on_command("消息计数初始化", permission=SUPERUSER, priority=10, block=True)


@init_cmd.handle()
async def handle_init(bot: Bot, event: GroupMessageEvent):
    """处理初始化命令"""
    try:
        await init_cmd.send("正在清空所有发言记录，请稍候...")
        
        with get_db_session() as session:
            session.query(MessageRecord).delete()
            session.commit()
        
        await init_cmd.send("所有发言记录已清空！")
        
    except Exception as e:
        logger.error(f"初始化命令处理失败: {e}")
        await init_cmd.send("初始化失败，请稍后重试")


def calculate_rankings(records: List[MessageRecord], target_user_id: str) -> dict:
    """计算用户在各时段的排名"""
    rankings = {}
    
    periods = {
        "today": "today_count",
        "yesterday": "yesterday_count",
        "week": "week_count",
        "month": "month_count",
        "year": "year_count",
        "total": "total_count"
    }
    
    for period, field in periods.items():
        # 按该字段排序
        sorted_records = sorted(records, key=lambda x: getattr(x, field), reverse=True)
        
        # 找到目标用户的排名
        for i, record in enumerate(sorted_records):
            if record.user_id == target_user_id:
                rankings[period] = i + 1
                break
        else:
            rankings[period] = None
    
    return rankings


def format_user_stats(record: MessageRecord, rankings: dict) -> str:
    """格式化用户统计信息"""
    username = record.username or record.user_id
    
    result = f"📊 {username} 的发言统计\n\n"
    
    stats = [
        ("今日", record.today_count, rankings.get("today")),
        ("昨日", record.yesterday_count, rankings.get("yesterday")),
        ("本周", record.week_count, rankings.get("week")),
        ("本月", record.month_count, rankings.get("month")),
        ("今年", record.year_count, rankings.get("year")),
        ("总计", record.total_count, rankings.get("total"))
    ]
    
    for period, count, rank in stats:
        rank_text = f"#{rank}" if rank else "#-"
        result += f"{period}: {count} 条 {rank_text}\n"
    
    return result.strip()


def format_ranking_list(records: List[MessageRecord], period: str, group_id: str) -> str:
    """格式化排行榜列表"""
    period_name = get_period_name(period)
    count_field = {
        "today": "today_count",
        "yesterday": "yesterday_count",
        "week": "week_count",
        "month": "month_count",
        "year": "year_count",
        "total": "total_count"
    }[period]
    
    result = f"🏆 {period_name}发言排行榜\n\n"
    
    total_messages = sum(getattr(record, count_field) for record in records)
    
    for i, record in enumerate(records, 1):
        username = record.username or record.user_id
        count = getattr(record, count_field)
        
        if config.message_counter_show_percentage and total_messages > 0:
            percentage = (count / total_messages) * 100
            result += f"{i}. {username}: {count} 条 ({percentage:.1f}%)\n"
        else:
            result += f"{i}. {username}: {count} 条\n"
    
    if config.message_counter_show_time:
        result += f"\n📅 生成时间: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}"
    
    return result.strip()


def format_group_ranking_list(group_stats: List[Tuple], period: str) -> str:
    """格式化群排行榜列表"""
    period_name = get_period_name(period)
    
    result = f"🏆 {period_name}群聊发言排行榜\n\n"
    
    total_messages = sum(stat.total_count for stat in group_stats)
    
    for i, stat in enumerate(group_stats, 1):
        group_name = stat.group_name or stat.group_id
        count = stat.total_count
        
        if config.message_counter_show_percentage and total_messages > 0:
            percentage = (count / total_messages) * 100
            result += f"{i}. {group_name}: {count} 条 ({percentage:.1f}%)\n"
        else:
            result += f"{i}. {group_name}: {count} 条\n"
    
    if config.message_counter_show_time:
        result += f"\n📅 生成时间: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}"
    
    return result.strip()


def get_period_name(period: str) -> str:
    """获取时间段名称"""
    names = {
        "today": "今日",
        "yesterday": "昨日",
        "week": "本周",
        "month": "本月",
        "year": "今年",
        "total": "总"
    }
    return names.get(period, "今日")


async def generate_ranking_image(records: List[MessageRecord], period: str, group_id: str) -> Optional[bytes]:
    """生成排行榜图片"""
    try:
        # 创建图片生成器
        generator = RankingImageGenerator()
        
        # 准备数据
        period_name = get_period_name(period)
        count_field = {
            "today": "today_count",
            "yesterday": "yesterday_count", 
            "week": "week_count",
            "month": "month_count",
            "year": "year_count",
            "total": "total_count"
        }[period]
        
        total_messages = sum(getattr(record, count_field) for record in records)
        
        ranking_data = []
        for record in records:
            count = getattr(record, count_field)
            percentage = (count / total_messages) * 100 if total_messages > 0 else 0
            
            # 获取头像base64数据
            avatar_base64 = ""
            if record.user_avatar:
                avatar_base64 = await get_avatar_base64_from_url_async(record.user_avatar)
                if avatar_base64:
                    avatar_base64 = f"data:image/jpeg;base64,{avatar_base64}"
            
            ranking_data.append({
                "name": record.username or record.user_id,
                "count": count,
                "percentage": percentage,
                "avatarBase64": avatar_base64 or ""  # 使用获取到的头像数据
            })
        
        # 构建数据结构
        data = {
            "rankingData": ranking_data,
            "rankTitle": "发言排行榜",
            "rankTimeTitle": period_name,
            "config": {
                "isUserMessagePercentageVisible": config.message_counter_show_percentage
            }
        }
        
        # 生成图片
        image_bytes = generator.generate_ranking_image(data)
        return image_bytes
        
    except Exception as e:
        logger.error(f"生成排行榜图片失败: {e}")
        return None